export default function MyPromise(executor) {
	const self = this;
	self.PromiseState = 'pending';
	self.PromiseResult = null;
	// 这个属性用来保存回调
	self.callbacks = [];

	function resolve(data) {
		// 改变状态
		if (self.PromiseState !== 'pending') return;
		self.PromiseState = 'fulfilled';
		self.PromiseResult = data;
		// 如果异步任务执行时
		setTimeout(() => {
			self.callbacks.forEach(callback => {
				if (callback.onResolved) {
					callback.onResolved(data);
				}
			})
		});
	}

	function reject(data) {
		if (self.PromiseState !== 'pending') return;
		self.PromiseState = 'rejected';
		self.PromiseResult = data;
		setTimeout(() => {
			self.callbacks.forEach(callback => {
				if (callback.onRejected) {
					callback.onRejected(data);
				}
			})
		});
	}

	try {
		// 立即调用执行器函数'
		executor(resolve, reject);
	} catch (e) {
		reject(e);
	}

}
// 添加then方法
MyPromise.prototype.then = function (onResolved, onRejected) {
	if (typeof onResolved !== "function") {
		onResolved = value => value;
	}
	if (typeof onRejected !== "function") {
		onRejected = reason => {
			throw reason;
		}
	}
	// 调用回调函数
	return new MyPromise((resolve, reject) => {
		let callback = (resolved) => {
			try {
				let result = resolved(this.PromiseResult);
				if (result instanceof MyPromise) {
					result.then(value => {
						resolve(value);
					}, reason => {
						reject(reason);
					})
				} else {
					resolve(result);
				}
			} catch (e) {
				reject(e);
			}
		}
		if (this.PromiseState === 'fulfilled') {
			setTimeout(() => {
				callback(onResolved)
			});

		}
		if (this.PromiseState === 'rejected') {
			setTimeout(() => {
				callback(onRejected)
			});
		}
		// 异步任务,需要在此保存回调函数
		if (this.PromiseState === 'pending') {
			this.callbacks.push({
				onResolved: () => {
					callback(onResolved);
				},
				onRejected: () => {
					callback(onRejected);
				}
			})
		}
	})

}
MyPromise.prototype.catch = function (onRejected) {
	return this.then(undefined, onRejected);
}
MyPromise.resolve = function (value) {
	return new MyPromise((resolve, reject) => {
		if (value instanceof MyPromise) {
			value.then(v => {
				resolve(v);
			}, r => {
				reject(r);
			})
		} else {
			resolve(value);
		}
	});
}
MyPromise.reject = function (value) {
	return new MyPromise((resolve, reject) => {
		reject(value);
	});
}
MyPromise.all = function (promises) {
	return new MyPromise((resolve, reject) => {
		let count = 0;
		let arr = [];
		for (let i = 0; i < promises.length; i++) {
			promises[i].then(v => {
				count++;
				arr[i] = v;
				if (count === promises.length) {
					resolve(arr);
				}
			}, r => {
				reject(r);
			})
		}
	})
}
MyPromise.race = function (promises) {
	return new MyPromise((resolve, reject) => {
		for (let i = 0; i < promises.length; i++) {
			promises[i].then(v => {
				resolve(v);
			}, r => {
				reject(r);
			})
		}
	})
}
